/**
 * AliPayService.java 
 * Copyright © 2015-3015, Seax Group
 * 
 * @author Liu Tao
 * @create 2015年3月10日
 */
package com.pshare.alipay.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.stereotype.Service;

import com.alipay.config.AlipayConfig;
import com.alipay.util.AlipayNotify;
import com.alipay.util.SignUtils;
import com.pshare.constant.SeaxConstants;
import com.pshare.service.PayCallback;
import com.pshare.wx.tool.CommonUtil;
import com.pshare.wx.tool.ConfigUtil;
import com.pshare.wx.tool.PayCommonUtil;
import com.tenpay.util.WXUtil;
import com.tenpay.util.XMLUtil;

/**
 * 微信支付接口 微信后台接收到请求后调用本服务器接口进行业务逻辑处理
 */
@Service
public class AliPayService {

	private static final Logger logger = Logger.getLogger(AliPayService.class);

	/**
	 * 付款完成的通知处理
	 * 
	 * @param request
	 * @param response
	 * @param callback
	 * @throws Exception
	 */
	public void handleNotify(HttpServletRequest request, HttpServletResponse response, PayCallback callback)
			throws Exception {
		PrintWriter out = response.getWriter();
		String buyerAccount = null;

		// 获取支付宝POST过来反馈信息
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			params.put(name, valueStr);
			if ("buyer_email".equals(name)) {
				buyerAccount = valueStr;
			}
		}

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		//支付金额
		String price=new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8") ;
		

		System.out.println("---out_trade_no:"+out_trade_no+"      trade_no:"+trade_no+"     trade_status:"+trade_status);

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

		//if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			// 请在这里加上商户的业务逻辑程序代码
			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			
			System.out.println("验证成功"+trade_status);

			if (trade_status.equals("TRADE_FINISHED")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 如果有做过处理，不执行商户的业务程序

				// 注意：
				// 该种交易状态只在两种情况下出现
				// 1、开通了普通即时到账，买家付款成功后。
				// 2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
			} else if (trade_status.equals("TRADE_SUCCESS")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 如果有做过处理，不执行商户的业务程序

				// 注意：
				// 该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。

				callback.doWork(out_trade_no, trade_no, price, buyerAccount,PayCallback.TYPE_ALIPAY);
			}else if (trade_status.equals("WAIT_BUYER_PAY")) {
				
			}

			// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

			out.println("success"); // 请不要修改或删除

			// ////////////////////////////////////////////////////////////////////////////////////////
//		} else {// 验证失败
//			out.println("fail");
//		}
		// ------------------------------
		// 处理业务完毕
		// ------------------------------
		out.flush();
		out.close();
	}

	/**
	 * 交易订单查询
	 * 
	 * @param orderNum 业务系统订单号
	 * @param payCode 支付系统订单号
	 * @return String
	 */
	public String queryTrans(String orderNumber, String payCode) throws Exception {
		if (StringUtils.isBlank(payCode) && StringUtils.isBlank(orderNumber)) {
			logger.error("payCode and orderNumber are all blank");
			return null;
		}

		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.put("appid", ConfigUtil.APP_ID);
		parameters.put("mch_id", ConfigUtil.MCH_ID);
		parameters.put("transaction_id", payCode);
		parameters.put("out_trade_no", orderNumber);
		parameters.put("nonce_str", WXUtil.getNonceStr());
		String sign = PayCommonUtil.createSign(SeaxConstants.UTF8, parameters);
		parameters.put("sign", sign);
		String requestXML = PayCommonUtil.getRequestXml(parameters);

		String result = CommonUtil.httpsRequest(ConfigUtil.CHECK_ORDER_URL, "POST", requestXML);
		System.out.println(result);

		String trade_state = null;
		try {
			Map<String, String> map = XMLUtil.doXMLParse(result);
			String returnCode = map.get("return_code");
			String resultCode = map.get("return_msg");
			if (returnCode.equalsIgnoreCase(SeaxConstants.SUCCESS)
					&& resultCode.equalsIgnoreCase(SeaxConstants.SUCCESS)) {
				trade_state = map.get("trade_state");
				logger.error(trade_state);
			} else {
				logger.error("-------------duang-----------");
			}
		} catch (JDOMException | IOException e) {
			e.printStackTrace();
		}

		return trade_state;
	}

	/**
	 * 获取支付订单信息
	 * 
	 * @param orderId
	 * @return String
	 */
	public String getPayInfo(String subject, String body, Double price, String outTradeNo) {
		// 订单
		String orderInfo = getOrderInfo(subject, body, price + "", outTradeNo);

		// 对订单做RSA 签名
		String sign = sign(orderInfo);
		try {
			// 仅需对sign 做URL编码
			sign = URLEncoder.encode(sign, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		// 完整的符合支付宝参数规范的订单信息
		final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();

		return payInfo;
	}

	/**
	 * create the order info. 创建订单信息
	 * 
	 */
	public String getOrderInfo(String subject, String body, String price, String outTradeNo) {
		// 签约合作者身份ID
		String orderInfo = "partner=" + "\"" + AlipayConfig.PARTNER + "\"";

		// 签约卖家支付宝账号
		orderInfo += "&seller_id=" + "\"" + AlipayConfig.SELLER + "\"";

		// 商户网站唯一订单号
		orderInfo += "&out_trade_no=" + "\"" + outTradeNo + "\"";

		// 商品名称
		orderInfo += "&subject=" + "\"" + subject + "\"";

		// 商品详情
		orderInfo += "&body=" + "\"" + body + "\"";

		// 商品金额
		orderInfo += "&total_fee=" + "\"" + price + "\"";

		// 服务器异步通知页面路径
		orderInfo += "&notify_url=" + "\"" + AlipayConfig.NOTIFY_URL + "\"";

		// 服务接口名称， 固定值
		orderInfo += "&service=\"mobile.securitypay.pay\"";

		// 支付类型， 固定值
		orderInfo += "&payment_type=\"1\"";

		// 参数编码， 固定值
		orderInfo += "&_input_charset=\"utf-8\"";

		// 设置未付款交易的超时时间
		// 默认30分钟，一旦超时，该笔交易就会自动被关闭。
		// 取值范围：1m～15d。
		// m-分钟，h-小时，d-天，1c-当天（无论交易何时创建，都在0点关闭）。
		// 该参数数值不接受小数点，如1.5h，可转换为90m。
		orderInfo += "&it_b_pay=\"30m\"";

		// extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
		// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

		// 支付宝处理完请求后，当前页面跳转到商户指定页面的路径，可空
		orderInfo += "&return_url=\"m.alipay.com\"";

		// 调用银行卡支付，需配置此参数，参与签名， 固定值 （需要签约《无线银行卡快捷支付》才能使用）
		// orderInfo += "&paymethod=\"expressGateway\"";

		return orderInfo;
	}

	/**
	 * sign the order info. 对订单信息进行签名
	 * 
	 * @param content 待签名订单信息
	 */
	public String sign(String content) {
		return SignUtils.sign(content, AlipayConfig.RSA_PRIVATE);
	}

	/**
	 * get the sign type we use. 获取签名方式
	 * 
	 */
	public String getSignType() {
		return "sign_type=\"RSA\"";
	}

}
